﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using DTO;
using System.ComponentModel;

namespace DAO
{
    public class BookDAO
    {
        private BookDTO CreateBookDTOFromEntity(Sach s)
        {
            BookDTO bookDto = new BookDTO
            {
                AuthorID = int.Parse( s.MaTacGia.ToString()),
                BookName = s.TenSach,
                BookCode = s.MaSach,
                ReceivePrice = float.Parse(s.GiaNhap.ToString()),
                BookCost = float.Parse( s.DonGia.ToString()),
                BookID = s.SachID,
                CategoryID = int.Parse( s.MaTheLoai.ToString()),
                StockQuantity = int.Parse( s.SoLuongTon.ToString())
            };

            return bookDto;
        }

        public BindingList<BookDTO> GetNewBindingList()
        {
            try
            {
                using (BookStoreEntities ent = new BookStoreEntities())
                {
                    BindingList<BookDTO> listBook = new BindingList<BookDTO>();
                    foreach (Sach book in ent.Saches.Where(b => b.SuDung == true).ToList())
                    {
                        BookDTO bookDto = CreateBookDTOFromEntity(book);
                        bookDto.CategoryName = ent.TheLoais.FirstOrDefault(c => c.TheLoaiID == bookDto.CategoryID).TenTheLoai;
                        bookDto.AuthorName = ent.TacGias.FirstOrDefault(c => c.TacGiaID == bookDto.AuthorID).TenTacGia;

                        listBook.Add(bookDto);
                    }

                    return listBook;
                }
            }
            catch
            {
                return null;
            }
        }

        public int InsertBook(BookDTO bookDto)
        {
            try
            {
                using (BookStoreEntities ent = new BookStoreEntities())
                {
                    Sach bookEnt = new Sach
                    {
                        MaSach = bookDto.BookCode,
                        TenSach = bookDto.BookName,
                        MaTheLoai = bookDto.CategoryID,
                        MaTacGia = bookDto.AuthorID,
                        SoLuongTon = 0,
                        SuDung = true,
                        DonGia = bookDto.BookCost,
                        GiaNhap = bookDto.ReceivePrice
                    };

                    if (ent.Saches.Count(t => t.SachID != null) > 0)
                    {
                        bookEnt.SachID = ent.Saches.Max(t => t.SachID) + 1;
                    }
                    else
                    {
                        bookEnt.SachID = 1;
                    }

                    ent.AddToSaches(bookEnt);

                    DocSequenceDAO docSeqDAO = new DocSequenceDAO();
                    docSeqDAO.UpdateNextDocSequence(DocSequence.Book.ToString());

                    ent.SaveChanges();

                    return bookEnt.SachID;
                }
            }
            catch
            {
                return -1;
            }
        }

        public bool UpdateBook(BookDTO bookDto)
        {
            try
            {
                using (BookStoreEntities ent = new BookStoreEntities())
                {
                    Sach bookEnt = ent.Saches.FirstOrDefault(c => c.SachID == bookDto.BookID);

                    bookEnt.TenSach = bookDto.BookName;
                    bookEnt.MaTacGia = bookDto.AuthorID;
                    bookEnt.MaTheLoai = bookDto.CategoryID;
                    bookEnt.DonGia = bookDto.BookCost;
                    bookEnt.GiaNhap = bookDto.ReceivePrice;

                    ent.SaveChanges();

                    return true;
                }
            }
            catch
            {
                return false;
            }
        }

        public bool UpdateQuantityFromReceiving(int id, int quantity)
        {
            try
            {
                using (BookStoreEntities ent = new BookStoreEntities())
                {
                    Sach sach = ent.Saches.FirstOrDefault(s => s.SachID == id);
                    sach.SoLuongTon += quantity;
                    ent.SaveChanges();
                    return true;
                }
            }
            catch
            {
                return false;
            }
        }

        public BookDTO GetBookByID(int ID)
        {
            try
            {
                using (BookStoreEntities ent = new BookStoreEntities())
                {
                    Sach bookEnt = ent.Saches.FirstOrDefault(c => c.SachID == ID);

                    BookDTO bookDto = CreateBookDTOFromEntity(bookEnt);

                    bookDto.CategoryName = ent.TheLoais.FirstOrDefault(c => c.TheLoaiID == bookDto.CategoryID).TenTheLoai;
                    bookDto.AuthorName = ent.TacGias.FirstOrDefault(a => a.TacGiaID == bookDto.AuthorID).TenTacGia;

                    return bookDto;
                }
            }
            catch
            {
                return null;
            }
        }

        public bool DeleteBook(int ID)
        {
            try
            {
                using (BookStoreEntities ent = new BookStoreEntities())
                {
                    Sach bookEnt = ent.Saches.FirstOrDefault(c => c.SachID == ID);
                    bookEnt.SuDung = false;
                    ent.SaveChanges();
                    return true;
                }
            }
            catch
            {
                return false;
            }
        }

        public bool CheckExistsCode(string code)
        {
            try
            {
                using (BookStoreEntities ent = new BookStoreEntities())
                {
                    int count = ent.Saches.Where(c => c.MaSach == code).Count();

                    if (count > 0)
                    {
                        return true;
                    }
                    else
                    {
                        return false;
                    }
                }
            }
            catch
            {
                return true;
            }
        }

        public List<BookReportDTO> GetListBookForReport(DateTime from, DateTime to)
        {
            List<BookReportDTO> listReport = new List<BookReportDTO>();
            using (BookStoreEntities ent = new BookStoreEntities())
            {
                List<Sach> listBook = ent.Saches.Where(s => s.SuDung == true).ToList();
                ReceivingDAO receiDAO =new ReceivingDAO();
                InvoiceDAO invoiceDAO = new InvoiceDAO();

                foreach (Sach s in listBook)
                {
                    BookReportDTO bookRpt = new BookReportDTO();
                    bookRpt.BookID = s.SachID;
                    bookRpt.BookName = s.TenSach;
                    bookRpt.AuthorName = ent.TacGias.First(t => t.TacGiaID == s.MaTacGia).TenTacGia;
                    bookRpt.CategoryName = ent.TheLoais.First(t => t.TheLoaiID == s.MaTheLoai).TenTheLoai;
                    bookRpt.StockQuantity = s.SoLuongTon ?? 0;
                    bookRpt.ReceiveQuantity = receiDAO.GetReceivingQuantity(s.SachID, from, to);
                    bookRpt.SellQuantity = invoiceDAO.GetQuantitySellForReport(s.SachID, from, to);

                    listReport.Add(bookRpt);
                }
            }

            return listReport;
        }
    }
}
